﻿/*************************************************************************************
 * 工    具：  HK_DotweenEaseShow
 * 
 * 描    述：  该工具可对Dotween内置Ease缓动动画进行预览，可查看所有缓动类型的动画曲线及相应预览动画
 * 
 * 版    本：  V1.0
 * 作    者：  京产肠饭
 * 
 * 创    建：  2023/02/11  V1.0
 * 
 * 链    接：  https://gitee.com/JingChanChangFan/hk_-unity-tools
*************************************************************************************/

using DG.Tweening;
using UnityEditor;
using UnityEngine;
using DG.Tweening.Core.Easing;

namespace HKTools
{
    public class HK_DotweenEaseShow : EditorWindow
    {
        Ease ease = Ease.Linear;
        float overShootOrAmplitude = DOTween.defaultEaseOvershootOrAmplitude;
        float period = DOTween.defaultEasePeriod;

        int pCount = 60;
        int pLength = 5;
        Vector2 curveInitPos = new Vector2(20, 70);

        Texture bgTex;
        Texture sphereTex;

        bool isAnim = false;
        float animTime = 0;
        float duration = 5;

        Vector2 animInitPos = new Vector2(400, 70);

        float animCurY;
        float animTargetY;

        [MenuItem("HKTools/Dotween Ease Show (Dotween动效预览工具)", priority = HK_MenuPriority.HK_DotweenEaseShow)]
        public static void ShowWindow()
        {
            GetWindow<HK_DotweenEaseShow>("Dotween Ease Show");
        }

        void OnEnable()
        {
            bgTex = GetBGTex();
            sphereTex = GetSphereTex();

            animCurY = animInitPos.y;
            animTargetY = animInitPos.y + 300 - sphereTex.height;
        }

        void OnDisable()
        {
            DestroyImmediate(bgTex);
            DestroyImmediate(sphereTex);
        }

        void OnGUI()
        {
            DrawUI();
            DrawBg();
            DrawEaseCurve();
            DrawSphere();
        }

        void DrawUI()
        {
            ease = (Ease)EditorGUILayout.EnumPopup("EaseType:", ease);
            EditorGUILayout.Space();
            if (GUILayout.Button("预览"))
            {
                isAnim = true;
                animTime = 0;
                animCurY = animInitPos.y;
            }
        }

        void Update()
        {
            if (isAnim)
            {
                animTime += 0.0025f;

                if (animTime > duration)
                {
                    animTime = duration;
                    isAnim = false;
                }

                float lerp = EaseManager.Evaluate(ease, null, animTime, duration, overShootOrAmplitude, period);

                animCurY = animInitPos.y + (animTargetY - animInitPos.y) * lerp;

                Repaint();
            }
        }

        // 绘制小球预览动画
        void DrawSphere()
        {
            GUI.DrawTexture(new Rect(animInitPos.x, animCurY, sphereTex.width, sphereTex.height), sphereTex);
        }

        // 绘制缓动动画曲线
        void DrawEaseCurve()
        {
            for (int i = 0; i < pCount; i++)
            {
                var x1 = i;
                var y1 = pCount * EaseManager.Evaluate(ease, null, x1, pCount, overShootOrAmplitude, period);

                var p1 = new Vector2(curveInitPos.x + x1 * pLength, curveInitPos.y + pCount * pLength - y1 * pLength);

                var x2 = i + 1;
                var y2 = pCount * EaseManager.Evaluate(ease, null, x2, pCount, overShootOrAmplitude, period);

                var p2 = new Vector2(curveInitPos.x + x2 * pLength, curveInitPos.y + pCount * pLength - y2 * pLength);

                Handles.color = Color.red;
                Handles.DrawLine(p1, p2, 1f);
            }
        }

        // 绘制背景
        void DrawBg()
        {
            GUI.DrawTexture(new Rect(curveInitPos.x, curveInitPos.y, pCount * pLength, pCount * pLength), bgTex);
            Handles.DrawLine(new Vector2(curveInitPos.x, curveInitPos.y + pCount * pLength), new Vector2(curveInitPos.x + pCount * pLength, curveInitPos.y + pCount * pLength), 1.5f);
            Handles.DrawLine(new Vector2(curveInitPos.x, curveInitPos.y), new Vector2(curveInitPos.x, curveInitPos.y + pCount * pLength), 1.5f);

            Handles.DrawLine(new Vector2(animInitPos.x - 30, animInitPos.y), new Vector2(animInitPos.x - 30, animInitPos.y + 300), 1f);
            GUI.Label(new Rect(animInitPos.x - 50, animInitPos.y - 20, 50, 20), "起始点");
            GUI.Label(new Rect(animInitPos.x - 50, animInitPos.y + 300, 50, 20), "结束点");
        }

        Texture GetBGTex()
        {
            var tex = new Texture2D(64, 64);
            Color c1 = new Color(0.5f, 0.5f, 0.5f, 0.82f);

            for (int y = 0; y < tex.height; ++y)
            {
                for (int x = 0; x < tex.width; ++x)
                {
                    tex.SetPixel(x, y, c1);
                }
            }
            tex.Apply();
            tex.filterMode = FilterMode.Point;
            tex.hideFlags = HideFlags.HideAndDontSave;
            return tex;
        }

        Texture GetSphereTex()
        {
            int r = 20;
            Texture2D tex = new Texture2D(r * 2, r * 2, TextureFormat.ARGB32, false);
            Vector2 center = new Vector2(r, r);

            Color color = Color.white;

            for (int i = 0; i < tex.height; i++)
            {
                for (int j = 0; j < tex.width; j++)
                {
                    float dis = Vector2.Distance(new Vector2(i, j), center);
                    if (dis > r)
                        color.a = 0;
                    else
                        color.a = 1;

                    tex.SetPixel(i, j, color);
                }
            }

            tex.Apply();
            tex.filterMode = FilterMode.Point;
            tex.hideFlags = HideFlags.HideAndDontSave;
            return tex;
        }
    }
}